
import urllib2
import urllib
import json
import threading
import time
import base64

class HttpRequest(object):
    """docstring for HttpRequest"""

    # def __init__(self, url, params=None, username=None, passwd=None):
    def __init__(self, url, params=None, username=None, passwd=None):
        super(HttpRequest, self).__init__()
        self.url = url

        if params != None:
            self.url += "?%s" % (urllib.urlencode(params))
        self.request = urllib2.Request(self.url)
        if username != None:
            basestr = base64.encodestring('%s:%s' % (username,passwd))[:-1]
            self.request.add_header('Authorization','Basic %s' % basestr)

        self.conn = None
        self.default_headers = {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
        for k in self.default_headers:
            self.add_header(k, self.default_headers[k])
        self.record_thread = None

    def add_header(self, key, val):
        self.request.add_header(key, val)

    def get_header(self, key):
        if self.conn.headers.has_key(key):
            return self.conn.headers[key]
        return None

    def post(self, data="", headers={}):
        for k in headers:
            self.add_header(k, headers[k])
        self.request.get_method = lambda: 'POST'
        if type(data) != str:
            data = json.dumps(data)
        self.request.add_data(data)
        try:
        	self.conn = urllib2.urlopen(self.request)
        except urllib2.URLError as e:
        	print "====", e.read(1000), "----"
        	raise e
        return self.conn.getcode()

    def json(self):
    	r = self.raw()
        return json.loads(r)

    def raw(self):
        respones_data = []
        while True:
            r = self.conn.read(1024)
            if len(r) == 0:
                break
            respones_data.append(r)
        return ''.join(respones_data)

    def async_record_json(self, callback, wait=False):
        def _async():
            self.record_flag = True
            while self.record_flag:
                json_obj = self.record_json()
                if json_obj == None:
                    break
                callback(json_obj, self.conn.headers)
        self.record_thread = threading.Thread(target=_async)
        self.record_thread.start()
        if wait:
            self.record_thread.join()

    def sync_record_json(self, callback):
        while True:
            json_obj = self.record_json()
            if json_obj == None:
                break
            callback(json_obj, self.conn.headers)

    def async_record_stop(self):
        self.record_flag = False

    def record_json(self):
        r = self.recordio()
        if r:
            return json.loads(r)
        return None

    def recordio(self):
        respones_data = []
        while True:
            bytes_len = []
            while True:
                c = self.conn.read(1)
                if c == "\n":
                    break
                elif c == '':
                	return None
                bytes_len.append(c)
            bytes_len = int("".join(bytes_len))
            if bytes_len == 0:
                break
            return self.conn.read(bytes_len)
        return None

# # headers = {
# # "Content-Type": "application/json",
# # "Accept": "application/json"
# # }

# data = """
# {
#    "type"       : "SUBSCRIBE",
#    "subscribe"  : {
#       "framework_info"  : {
#         "user" :  "foo",
#         "name" :  "Example HTTP Framework",
#         "roles": ["test"],
#         "capabilities" : [{"type": "MULTI_ROLE"}]
#       }
#   }
# }
# """

# # hr = HttpRequest("http://172.17.0.2:5050/api/v1/scheduler")
# hr = HttpRequest("http://172.17.0.2:5050/state")
# r = hr.post(data=data)
# print r
# # r = hr.raw()
# # print r

# r = hr.json()
# print r
# # r = hr.recordio()
# # print r
# # r = hr.record_json()
# # print r
